package org.apache.commons.graph.algorithms.visit.internal

import org.apache.commons.graph.DirectedGraph
import org.apache.commons.graph.Graph
import org.apache.commons.graph.algorithms.visit.BaseGraphVisitHandler
import org.apache.commons.graph.algorithms.visit.VisitState
import org.apache.commons.graph.model.BaseMutableGraph
import org.apache.commons.graph.model.DirectedMutableGraph
import org.apache.commons.graph.model.UndirectedMutableGraph

/**
 * Internal Visitor helper that produces the search tree.
 *
 * @param <V> the Graph vertices type.
 * @param <E> the Graph edges type.
</E></V> */
internal class VisitGraphBuilder<V, E, G : Graph<V, E>> : BaseGraphVisitHandler<V, E, G, Graph<V, E>>() {
    private var visitGraph: BaseMutableGraph<V, E>? = null

    /**
     * {@inheritDoc}
     */
    override fun discoverEdge(head: V, edge: E, tail: V): VisitState {
        visitGraph!!.addEdge(head, edge, tail)
        return VisitState.CONTINUE
    }

    /**
     * {@inheritDoc}
     */
    override fun discoverGraph(graph: G) {
        visitGraph = if (graph is DirectedGraph<*, *>) {
            DirectedMutableGraph()
        } else {
            UndirectedMutableGraph()
        }

        for (vertex in graph.vertices) {
            visitGraph!!.addVertex(vertex)
        }
    }

    /**
     * {@inheritDoc}
     */
    override fun onCompleted(): Graph<V, E> {
        return visitGraph!!
    }
}